﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using ScottPlot;
using ReactiveChannelMessaging.Core;
using System.Windows.Forms;

public class RealTimeDataProcessor : IDisposable
{
    private readonly IObservable<DataMessage> _processedMessages; // 处理后的消息流
    private readonly FormsPlot _formsPlot; // ScottPlot图表控件
    private readonly Dictionary<string, (ScottPlot.Plottable.SignalPlotXY Plot, double[] XData, double[] YData)> _plots; // 存储图表和数据
    private readonly List<IDisposable> _subscriptions; // 订阅列表
    private int _currentIndex; // 当前数据索引
    private readonly object _plotLock = new object(); // 图表锁对象

    /// <summary>
    /// 实时数据处理器构造函数
    /// </summary>
    /// <param name="formsPlot">ScottPlot图表控件</param>
    /// <param name="processedMessages">处理后的消息流</param>
    public RealTimeDataProcessor(FormsPlot formsPlot, IObservable<DataMessage> processedMessages)
    {
        _formsPlot = formsPlot; // 初始化ScottPlot图表控件
        _processedMessages = processedMessages; // 初始化消息流
        _plots = new Dictionary<string, (ScottPlot.Plottable.SignalPlotXY, double[], double[])>(); // 初始化图表字典
        _subscriptions = new List<IDisposable>(); // 初始化订阅列表
        _currentIndex = 0; // 初始化数据索引
        SetupRealTimeProcessing(); // 设置实时处理
    }

    /// <summary>
    /// 设置实时数据处理
    /// </summary>
    private void SetupRealTimeProcessing()
    {
        var messageSubscription = _processedMessages
            .ObserveOn(SynchronizationContext.Current) // 确保在UI线程更新
            .Subscribe(message =>
            {
                try
                {
                    // 解析消息内容中的多个数据序列
                    var dataSeries = ParseContentToDataSeries(message.Content);

                    lock (_plotLock)
                    {
                        foreach (var series in dataSeries)
                        {
                            // 动态生成曲线
                            UpdateOrAddPlot(series.Key, series.Value);
                        }
                    }

                    _formsPlot.Refresh(); // 刷新图表
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error processing message: {ex.Message}"); // 记录处理消息时的错误
                }
            });

        _subscriptions.Add(messageSubscription); // 添加订阅到列表
    }

    /// <summary>
    /// 解析消息内容为数据序列
    /// </summary>
    /// <param name="content">消息内容字符串</param>
    /// <returns>数据序列列表</returns>
    private List<KeyValuePair<string, double>> ParseContentToDataSeries(string content)
    {
        // 示例解析逻辑：假设内容格式为 "Sensor1:0.5,Sensor2:0.8"
        var series = new List<KeyValuePair<string, double>>();
        var parts = content.Split(','); // 按逗号分割字符串
        foreach (var part in parts)
        {
            var kv = part.Split(':'); // 按冒号分割每个部分
            if (kv.Length == 2 && double.TryParse(kv[1], out var value))
            {
                series.Add(new KeyValuePair<string, double>(kv[0].Trim(), value)); // 添加解析后的数据序列
            }
        }
        return series;
    }

    /// <summary>
    /// 更新或添加图表
    /// </summary>
    /// <param name="key">数据序列的键（传感器名称）</param>
    /// <param name="value">数据序列的值</param>
    private void UpdateOrAddPlot(string key, double value)
    {
        if (!_plots.ContainsKey(key))
        {
            // 创建新曲线
            var xs = new double[1000]; // 初始化X轴数据数组，长度为1000
            var ys = new double[1000]; // 初始化Y轴数据数组，长度为1000
            var plot = _formsPlot.Plot.AddSignalXY(xs, ys); // 添加信号曲线到图表
            plot.LineWidth = 2;
            plot.Color = GenerateColor(key);
            plot.Label = $"{key} (0.00)"; // 初始显示格式

            _plots[key] = (plot, new double[1000], new double[1000]);
        }
        else
        {
            // 更新数据和标签
            var (plot, xData, yData) = _plots[key];
            UpdateRollingArray(xData, yData, value);
            plot.Label = $"{key}: {value:F2}";
        }
    }
    private void UpdateRollingArray(double[] xData, double[] yData, double value)
    {
        // 高效滚动数组实现
        Array.Copy(xData, 1, xData, 0, xData.Length - 1);
        Array.Copy(yData, 1, yData, 0, yData.Length - 1);

        xData[^1] = _currentIndex;
        yData[^1] = value;

        _currentIndex++;


        // 确保在UI线程中刷新图表
        if (_formsPlot.InvokeRequired)
        {
            _formsPlot.Invoke(new Action(() => _formsPlot.Refresh())); // 在UI线程中刷新图表
        }
        else
        {
            _formsPlot.Refresh(); // 刷新图表
        }
    }
    /// <summary>
    /// 基于键生成不同颜色
    /// </summary>
    /// <param name="key">数据序列的键（传感器名称）</param>
    /// <returns>生成的颜色</returns>
    private System.Drawing.Color GenerateColor(string key)
    {
        var hash = key.GetHashCode(); // 获取键的哈希值
        var r = (byte)(hash & 0xFF); // 提取红分量
        var g = (byte)((hash >> 8) & 0xFF); // 提取绿分量
        var b = (byte)((hash >> 16) & 0xFF); // 提取蓝分量
        return System.Drawing.Color.FromArgb(r, g, b); // 生成颜色
    }

    /// <summary>
    /// 释放资源
    /// </summary>
    public void Dispose()
    {
        foreach (var subscription in _subscriptions)
        {
            subscription.Dispose(); // 释放每个订阅
        }

        _subscriptions.Clear(); // 清空订阅列表
    }
}
